import dayjs from 'dayjs';

/**
 * @desc  格式化时间
 * @param {(Date)} time
 * @param {string} format
 * @returns {string | null}
 */
export function formatDateTime(time = new Date(), format = 'YYYY-MM-DD HH:mm:ss') {
  return dayjs.apply(time).format(format);
}

export function formatDate(date = undefined, format = 'YYYY-MM-DD') {
  return formatDateTime(date, format);
}

/**
 * @desc  函数节流
 * @param {Function} fn
 * @param {Number} wait
 * @returns {Function}
 */
export function throttle(fn, wait) {
  let context, args;
  let previous = 0;

  return function () {
    let now = +new Date();
    context = this;
    args = arguments;
    if (now - previous > wait) {
      fn.apply(context, args);
      previous = now;
    }
  };
}

/**
 * @desc  函数防抖
 * @param {Function} method
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(method, wait, immediate) {
  let timeout;
  return function (...args) {
    let context = this;
    if (timeout) {
      clearTimeout(timeout);
    }
    // 立即执行需要两个条件，一是immediate为true，二是timeout未被赋值或被置为null
    if (immediate) {
      /**
       * 如果定时器不存在，则立即执行，并设置一个定时器，wait毫秒后将定时器置为null
       * 这样确保立即执行后wait毫秒内不会被再次触发
       */
      let callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait);
      if (callNow) {
        method.apply(context, args);
      }
    } else {
      // 如果immediate为false，则函数wait毫秒后执行
      timeout = setTimeout(() => {
        /**
         * args是一个类数组对象，所以使用fn.apply
         * 也可写作method.call(context, ...args)
         */
        method.apply(context, args);
      }, wait);
    }
  };
}

/**
 * @desc blob转base64
 * @param {Blob} blob
 * @return {Promise}
 */
export function blobToBase64(blob) {
  return new Promise((resolve) => {
    const fileReader = new FileReader();
    fileReader.onload = (e) => {
      resolve(e.target.result);
    };
    fileReader.readAsDataURL(blob);
  });
}

/**
 * @desc 扁平结构转树结构
 * @param {Array} data
 * @param {string} pidName
 * @param {string} idName
 * @param {string} pid
 * @return {Array}
 */
export function dataToTree(data, pidName = 'pid', idName = 'id', pid = '1000000000000000000') {
  if (!data) return [];
  let res = [];
  let loopList = data.filter((ele) => {
    return ele[pidName] == pid;
  });
  if (loopList && loopList.length) {
    let children = [];
    loopList.forEach((im) => {
      if (im.flag) return;
      children = dataToTree(data, pidName, idName, im[idName]);
      if (children && children.length) {
        im.children = children;
      } else {
        im.children = undefined;
      }
    });
    res.push(...loopList);
    return res;
  } else {
    return [];
  }
}

/**
 * @desc 重置ref对象
 * @param {Object} initial 初始值对象
 * @param {Ref<Object>} targetRef 需要初始化的数据
 * @return {null}
 */
export function resetRef(initial, targetRef) {
  if (!initial) return Error('没有检测到初始值对象(initial)');
  if (!targetRef) return Error('没有检测到需要初始化的数据(targetRef)');
  Object.keys(initial).forEach((key) => {
    if (targetRef.hasOwnProperty(key)) {
      targetRef[key] = initial[key];
    }
  });
}
/**
 * @desc 获取时间状态
 * @return {String}
 */
export function getTimeState() {
  let timeNow = new Date();
  let hours = timeNow.getHours();
  if (hours >= 6 && hours <= 10) return `早上好 ⛅`;
  if (hours >= 10 && hours <= 14) return `中午好 🌞`;
  if (hours >= 14 && hours <= 18) return `下午好 🌞`;
  if (hours >= 18 && hours <= 24) return `晚上好 🌛`;
  if (hours >= 0 && hours <= 6) return `凌晨好 🌛`;
}

/**
 * @desc 格式化时间
 * @param {any} timeStr 初始时间
 * @param {String} format 需要格式化的类型
 * @return {String}
 */
export function formatTime(timeStr, format) {
  let time = null;
  if (/^\d{13}$/.test(timeStr)) time = Number(timeStr);
  else time = timeStr;
  return dayjs(new Date(time)).format(format);
}

export function bytesToSize(bytes) {
  if (bytes === 0) return '0 B';
  let k = 1024,
    sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
    i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}

export const downloadFileByBlob = (res) => {
  let headersName = '';
  if (res.headers['content-disposition']) {
    headersName = decodeURI(res.headers['content-disposition'].split(';')[1].match(/filename="([^"]+)"/)?.[1]);
  } else {
    headersName = '文件名称';
  }
  let fileName = decodeURI(headersName);
  let blob = new Blob([res.data]);
  // for IE
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, fileName);
    $message.success('下载成功');
  } else {
    // for Non-IE (chrome, firefox etc.)
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = fileName;
    link.click();
    window.URL.revokeObjectURL(link.href);
    $message.success('下载成功');
  }
};

export function download(url, filename) {
  let link = document.createElement('a');
  let body = document.querySelector('body');
  link.href = url;
  link.download = filename;
  // fix Firefox
  link.style.display = 'none';
  body.appendChild(link);
  link.click();
  body.removeChild(link);
  window.URL.revokeObjectURL(link.href);
}

export function rdmRgbColor() {
  //随机生成RGB颜色
  const arr = [];
  for (let i = 0; i < 3; i++) {
    // 暖色
    // arr.push(Math.floor(Math.random() * 128 + 64));
    // 亮色
    arr.push(Math.floor(Math.random() * 128 + 128));
  }
  const [r, g, b] = arr;
  // rgb颜色
  // var color=`rgb(${r},${g},${b})`;
  // 16进制颜色
  const color = `#${r.toString(16).length > 1 ? r.toString(16) : '0' + r.toString(16)}${
    g.toString(16).length > 1 ? g.toString(16) : '0' + g.toString(16)
  }${b.toString(16).length > 1 ? b.toString(16) : '0' + b.toString(16)}`;
  return color;
}
